//
//  fselect.swift
//  takeaway
//
//  Created by zhuxietong on 2021/3/1.
//

import Foundation
import Eelay
open class FMultipleOptionKit:FOptionKit{
    
    @objc open override func pressAction(){
        self.delegate?.active(onwer: self, actionID: "select", data: mo.model)
    }
    
}
open class FOptionKit:MoDisplayNode{
    public let bt = ASButtonNode()
    public let label = ASTextNode2()
    public var isSelect:Bool{
        get{
            return mo.model["selected",""] == "YES"
        }
        set{
            mo.model["selected"] = newValue ? "YES" : "NO"
            bt.isSelected = newValue
            updateSelect(select: newValue)
        }
    }
    open func updateSelect(select:Bool) {
        if select{
            bt.bsui.background(color: UIColor._tint.alpha(0.1)).set(radius: 3, width: 1, color: UIColor._tint.alpha(0.8))
        }else{
            let border = UIColor.color(light: "#aaa", dark: "#666")
            bt.bsui.background(color: UIColor._tableBackground.alpha(0.3)).set(radius: 3, width: 1, color: border)
        }
    }
    open override func mo_model_reload() {
        isSelect = mo.model["selected",""] == "YES"
        bt.ui.ntitle(title: mo.model["name",""]).stitle(title: mo.model["name",""]).padding(insets: [7,18]).scolor(color: ._tint).ncolor(color: UIColor.color(light: "#aaa", dark: "#666"))
    }
    open override func addLayoutRules() {
        
        bt.addTarget(self, action: #selector(pressAction), forControlEvents: .touchUpInside)
    }
    
    @objc open func pressAction(){
        if bt.isSelected{
            return
        }
        self.isSelect = true
        self.delegate?.active(onwer: self, actionID: "select", data: mo.model)
    }
    
    
    open override func specGetter() -> _Spec {
        return .inset([], [16,0,0,0], child: bt.Spec)
    }
}

open class FTextOption:FOptionKit {
    public let titleL = ASTextNode2()
    public let markImg = ASImageNode()
    open override func updateSelect(select:Bool) {
        if select{
            
//            bt.bsui.background(color: UIColor._tint.alpha(0.1)).set(radius: 3, width: 1, color: UIColor._tint.alpha(0.8))
            titleL.attributedText = mo.model["name",""].ui.font11.color(color: ._tint).astring
            markImg.image = UIImage(named: "xz_mark_s")?.rt_tintedImage(with: ._tint)
        }else{
//            let border = UIColor.color(light: "#aaa", dark: "#666")
//            bt.bsui.background(color: UIColor._tableBackground.alpha(0.3)).set(radius: 3, width: 1, color: border)
            titleL.attributedText = mo.model["name",""].ui.font11.color(color: ._weak).astring
            markImg.image = UIImage(named: "xz_mark_s")?.rt_tintedImage(with: ._weak)
            
        }
    }
    
    open override func mo_model_reload() {
        isSelect = mo.model["selected",""] == "YES"
    }
    
    open override func specGetter() -> _Spec {
        return _Spec.inset([], [0,0,0,0], child: _Spec.stack(["h|8",&-.center], childs: [
            markImg[14,"14"],
            titleL.Spec
        ]).addOver(bt.Spec))
    }
}


open class FSelect1<Kit:FOptionKit>:FSelect<Kit>{
    open override func specGetter() -> _Spec {
        return .inset([], [0,0,0,0], child: .stack(["h|6",&-.center], childs: [
            lableNode.Spec,
            listV[_grow(1),_shrink(1)]
        ]))
    }
    open override var _lable:NSAttributedString{
        get{
            if props.required{
                return "* ".ui.bfont14.color(color: .systemRed).astring + label.ui.font(font: labelStyle.font).color(color: labelStyle.color).astring
            }
            
            return label.ui.font(font: labelStyle.font).color(color: labelStyle.color).astring
        }
    }
    
}

open class FMultipleSelect<Kit:FOptionKit>:FField, EeActionDelegate{
    public enum Mode {
        case multiple
        case single
    }
    
    public var mode:Mode = .multiple
    open override var defaultProps: [FProps]{
        get{
            let v:FVerify = .method {[weak self] (v) -> FVerifyResult in
                guard let `self` = self else{return .success(value: v)}
                let limit = self.props.num_limit

                guard let l = v as? [Any] else {
                    return .nil
                }
//                print("_DDD____S",limit.min,l.count)
                
                if l.count < limit.min{
                    return .error(limit.minMask)
                }
                if l.count > limit.max{
                    return .error(limit.maxMask)
                }
                return .success(value: v)
            }
            return [.type(.select),.verify(v)]
        }
    }
    
    open override func didSetProps() {
        super.didSetProps()
    }
    
 
    
    
    
    public func active(onwer: Any, actionID: String, data: NSMutableDictionary) {
        switch mode {
        case .single:
            if actionID == "select"{
                self.update(value: data["id",""], edit: .select)
                guard let k = onwer as?FOptionKit else {return}
                for kit in listV.nodes {
                    if kit !== k{
                        if kit.isSelect{kit.isSelect = false}
                    }
                }
            }
        default:
            if actionID == "select"{
    //            self.update(value: data["id",""], edit: .select)
                guard let k = onwer as?FOptionKit else {return}
                
                let count = listV.nodes.filter{$0.isSelect}.count
                if !k.isSelect{
                    if count >= self.props.num_limit.max {
                        props.num_limit.maxMask.alert()
                        return
                    }
                }
                k.isSelect = !k.isSelect
                updateValue(edit: .select)
            }
            if actionID == "update"{
                updateValue(edit: .reply)
            }
        }
        
    }
    open func updateValue(edit:FEdit) {
        let kits = listV.nodes.filter{$0.isSelect}
        var items:[String] = []
        for kit in kits {
            items.append(kit.mo.model["id",""])
        }
        update(value: items, edit: edit)
    }
    
    public let listV = JoRuleNode<Kit>()
    open override func addLayoutRules() {
        super.addLayoutRules()
        listV.nodePath = "list"
        listV.delegate = self
        listV.space = 16
    }
    
    public var selectIds:[String]{
        var ids:[String] = []
        if let arr = value as? [String]{
            ids = arr
        }
        if let str = value as? String{
            ids = str.split(separator: ",").map({"\($0)"})
        }
        
        return ids
    }
    open override func update(_ prop:FProps){
        props.update(prop)
        loadProps()
        switch mode {
        case .multiple:
            switch prop {
            case .options(let options):
//                print("---kkkkkk--",options)
                let ops = options.mutable_array
                for item in Each<NSMutableDictionary>(ops) {
                    if selectIds.contains(item["id",""]){
                        item["selected"] = "YES"
                    }
                }
                listV.nodePath = "list"
                listV.mo.model = ["list":ops].mutable_dictionary
                setNeedsLayout()
                layoutIfNeeded()
            default:
                break
            }
        default:
            switch prop {
            case .options(let options):
                let ops = options.mutable_array
                for item in Each<NSMutableDictionary>(ops) {
                    if item["id",""] == "\(value)"{
                        item["selected"] = "YES"
                    }
                }
                listV.nodePath = "list"
                listV.mo.model = ["list":ops].mutable_dictionary
                setNeedsLayout()
                layoutIfNeeded()
            default:
                break
            }
        }
       
    }

    open override var statusObject: NSMutableDictionary{
        get{
            let obj = NSMutableDictionary()
            for kit in listV.nodes {
                let item = kit.mo.model
                if item["id","XXXDDD___"] == "\(value)"{
                    return item
                }
            }
            return obj
        }
    }
    open override func didInit() {
        let ops = props.options.mutable_array
        for item in Each<NSMutableDictionary>(ops) {
            if item["id","XXX"] == "\(value)"{
                item["selected"] = "YES"
            }
        }
        listV.mo.model = ["list":ops].mutable_dictionary

    }
    open override func specGetter() -> _Spec {
        return .inset([], [0,0,0,0], child: .stack(["v|6",&-.stretch], childs: [
            .if(label.len > 0, spec:  lableNode.Spec),
            listV.Spec
        ]))
    }
    
}


open class FSelect<Kit:FOptionKit>:FField, EeActionDelegate{
    open override var defaultProps: [FProps]{
        get{
            return [.type(.select),.verify(.reg("\\S+"))]
        }
    }
   
    open func active(onwer: Any, actionID: String, data: NSMutableDictionary) {
        if actionID == "select"{
//            print("___MMM",data)
            self.update(value: data["id",""], edit: .select)
//            guard let k = onwer as?FOptionKit else {return}
//            for kit in listV.nodes {
//                if kit !== k{
//                    if kit.isSelect{kit.isSelect = false}
//                }
//            }
        }
    }

    
    public let listV = JoRuleNode<Kit>()
    
    open override func addLayoutRules() {
        super.addLayoutRules()
        listV.nodePath = "list"
        listV.delegate = self
        listV.space = 16
    }
    
    open override func update(_ prop:FProps){
        props.update(prop)
        loadProps()
        switch prop {
        case .options(let options):
            let ops = options.mutable_array
            for item in Each<NSMutableDictionary>(ops) {
                if item["id",""] == "\(value)"{
                    item["selected"] = "YES"
                }
            }
            listV.nodePath = "list"
            listV.mo.model = ["list":ops].mutable_dictionary
        default:
            break
        }
    }
    open override func updateDispaly() {
        let v = "\(value)"
//        print("_))))|",v)
        for item in Each<NSMutableDictionary>(listV.mo.model.get(node: listV.nodePath, defaultV: NSMutableArray())) {
            if item["id",""] == v{
                item["selected"] = "YES"
            }else{
                item["selected"] = "NO"
            }
//            print("++++LLL",item)
        }
        for k in listV.nodes {
            k.mo_model_reload()
        }
        
        
    }

    open override var statusObject: NSMutableDictionary{
        get{
            let obj = NSMutableDictionary()
            for kit in listV.nodes {
                let item = kit.mo.model
                if item["id","$$$"] == "\(value)"{
                    return item
                }
            }
            return obj
        }
    }
    open override func didInit() {
        let ops = props.options.mutable_array
        for item in Each<NSMutableDictionary>(ops) {
            if item["id","XXX"] == "\(value)"{
                item["selected"] = "YES"
            }
        }
        listV.mo.model = ["list":ops].mutable_dictionary

    }
    open override func specGetter() -> _Spec {
        return .inset([], [0,0,16,0], child: .stack(["v|6",&-.stretch], childs: [
            .if(label.len > 0, spec: lableNode.Spec),
            listV.Spec
        ]))
    }
    
}
